package com.example.springmall.interceptor;

import com.example.springmall.exception.BusinessException;
import com.example.springmall.exception.UnauthorizedException;
import com.example.springmall.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Optional;

@Component
public class LoginInterceptor implements HandlerInterceptor {
    private static final String TOKEN_COOKIE_NAME = "token";
    private static final String TOKEN_COOKIE_PATH = "/";
    private static final int TOKEN_COOKIE_MAX_AGE = 24 * 60 * 60; // 24小时，单位：秒

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 1. 首先尝试从请求头中获取token
        String token = request.getHeader(TOKEN_COOKIE_NAME);

        // 2. 如果请求头中没有token，则尝试从Cookie中获取
        if (StringUtils.isEmpty(token)) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                Optional<Cookie> tokenCookie = Arrays.stream(cookies)
                        .filter(cookie -> TOKEN_COOKIE_NAME.equals(cookie.getName()))
                        .findFirst();

                if (tokenCookie.isPresent()) {
                    token = tokenCookie.get().getValue();
                }
            }
        }

        // 3. 校验token
        if (StringUtils.isEmpty(token)) {
            throw new UnauthorizedException("未登录");
        }

        // 4. 解析token获取用户信息
        try {
            Claims claims = JwtUtil.parseToken(token);
            // 将用户ID存入request
            request.setAttribute("userId", claims.getSubject());

            // 5. 刷新Cookie中的token
            Cookie cookie = new Cookie(TOKEN_COOKIE_NAME, token);
            cookie.setPath(TOKEN_COOKIE_PATH);
            cookie.setMaxAge(TOKEN_COOKIE_MAX_AGE);
            cookie.setHttpOnly(true); // 防止XSS攻击
            response.addCookie(cookie);

            return true;
        } catch (Exception e) {
            // 6. token解析失败，清除Cookie
            Cookie cookie = new Cookie(TOKEN_COOKIE_NAME, null);
            cookie.setPath(TOKEN_COOKIE_PATH);
            cookie.setMaxAge(0);
            response.addCookie(cookie);
            throw new BusinessException("登录已过期");
        }
    }
} 